// 所有服务器列表
var listOfServers = ["n00dles","foodnstuff","sigma-cosmetics","joesguns","hong-fang-tea","harakiri-sushi","iron-gym","zer0","max-hardware","CSEC","nectar-net","neo-net","omega-net","phantasy","silver-helix","the-hub","computek","avmnite-02h","netlink","johnson-ortho","crush-fitness","rothman-uni","zb-institute","catalyst","I.I.I.I","syscore","summit-uni","alpha-ent","lexo-corp","millenium-fitness","rho-construction","aevum-police","galactic-cyber","aerocorp","global-pharm","snap-fitness","omnia","deltaone","unitalife","defcomm","icarus","univ-energy","solaris","zeus-med","nova-med","infocomm","taiyang-digital","zb-def","microdyne","run4theh111z","titan-labs","applied-energetics","helios","vitalife","fulcrumtech","stormtech","omnitek","4sigma","kuai-gong",".","nwo","powerhouse-fitness","b-and-a","blade","clarkinc","ecorp","The-Cave","fulcrumassets","megacorp"]
;

/**
 * 筛选目标服务器
 * 条件:可黑,有钱,
 * @return 服务器名
 */
function getTargetServer(ns)
{
  // 策略7:通过试用grow得出的成长速度最高的服务器,对应的程序是server_researching.js
  return "omega-net";
  
  const hackLevel = ns.getHackingLevel();
  // ns.tprint("当前级别",hackLevel);

  // 最富的可黑的服务器
  var mostRichServer;
  // 上面指代的服务器, 钱的上限是多少
  var maxRichServerMoney=0;

  for(let i=0;i<listOfServers.length;++i)
  {
    let strServerName = listOfServers[i];
    var requireHackingLevel = ns.getServerRequiredHackingLevel(strServerName);
    // 选择hack目录的筛选条件:
    if(requireHackingLevel>hackLevel)continue;

    var maxMoney = ns.getServerMaxMoney(strServerName);
    // 选择hack目录的筛选条件2:
    if(!maxMoney)continue;

    var AnalyzeChance = ns.hackAnalyzeChance(strServerName);
    var growth = ns.getServerGrowth(strServerName);
    //策略2:*chanceOfHack 最大数值
    var value2 = maxMoney * AnalyzeChance;
    //策略3:*chanceOfHack*growth 最大数值
    var value3 = maxMoney * AnalyzeChance*growth;
    //策略4:growth
    var value4 = growth;
    var growTime = ns.getGrowTime(strServerName);
    //ns.tprint("目标服务器GrowTime:",growTime);
    var hackTime=ns.getHackTime(strServerName);
    //ns.tprint("目标服务器hackTime:",hackTime);
    //策略5:/(growTime+hackTime)
    var value5 = maxMoney/(growTime+hackTime);
    //策略6:/(growTime+hackTime)*chanceOfHack
    var value6 = maxMoney/(growTime+hackTime)*AnalyzeChance;
    if(maxRichServerMoney<value4)
    {
      mostRichServer = strServerName;
      maxRichServerMoney=value4;
    }
    else
    {
      continue;
    }
    ns.tprint(strServerName,"的最大钱数:",maxMoney/1000000.0,"m");
    ns.tprint(strServerName,"的growth:",ns.getServerGrowth(strServerName));
    var chanceOfHack = ns.hackAnalyzeChance(strServerName);
    ns.tprint(strServerName,"的chanceOfHack:",chanceOfHack);
    ns.tprint("目标服务器hackTime:",hackTime);
    ns.tprint("目标服务器GrowTime:",growTime);
    ns.tprint("目标服务器AnalyzeChance:",AnalyzeChance);
    //var maxRam = ns.getServerMaxRam(strServerName);
    // ns.tprint(strServerName,"的RAM大小:",maxRam);
    // ns.tprint(strServerName,"所需hack级别:",requireHackingLevel);

    var hackDifficulty = ns.getServer(strServerName).hackDifficulty;
    // ns.tprint(strServerName,"hack难度:",hackDifficulty,"%");


    ns.tprint("\n");
  }// END for
  
  // ns.tprint("最富的服务器:",mostRichServer);
  return mostRichServer;
}



/**
 * 打通目前能打通的所有服务器
 */
function rootAllServer(ns)
{
  var allHackedServer=[];
  for(let i=0;i<listOfServers.length;++i)
  {
    let strServerName = listOfServers[i];
    let objServer = ns.getServer(strServerName);
    let portOpen = 0;
    let hasNuke = false;
    if(ns.fileExists("BruteSSH.exe","home"))
    {
      ns.brutessh(strServerName);      
      ++portOpen;
    }
    if(ns.fileExists("FTPCrack.exe","home"))
    {
      ns.ftpcrack(strServerName); 
      ++portOpen;
    }
    if(ns.fileExists("relaySMTP.exe","home"))
    {
      ns.relaysmtp(strServerName); 
      ++portOpen;
    }
    //HTTPWorm.exe
    if(ns.fileExists("HTTPWorm.exe","home"))
    {
      ns.httpworm(strServerName); 
      ++portOpen;
    }
    //SQLInject.exe
    if(ns.fileExists("SQLInject.exe","home"))
    {
      ns.sqlinject(strServerName); 
      ++portOpen;
    }

    let portsRequire = ns.getServerNumPortsRequired(strServerName);
    if(portsRequire<=portOpen)
    {
      ns.nuke(strServerName);
      hasNuke = true;
    }
    //ns.getServer(strServerName)
    // ns.tprint("服务器:",strServerName)
    // ns.tprint("nuke?",hasNuke?"YES":"NO");
    let hasRoot= ns.hasRootAccess(strServerName);
    // ns.tprint("root?",hasRoot?"YES":"NO");
    // 添加条件, 有RAM的服务器
    if(hasRoot&&ns.getServerMaxRam(strServerName))
    {
      allHackedServer.push(strServerName);
    }
  }
  allHackedServer.push("home");
  return allHackedServer;
}// END rootAllServer


/**
 * 轮换执行3种单一脚本
 */
var counting=0;
function execScriptOnServer(ns,strServerName,targetServerName)
{
  var scripts = ["/script/grow.js","/script/hack.js","/script/weaken.js"];
  ns.exec(scripts[counting],strServerName,1,targetServerName);
  // 计数轮换
  ++counting;
  if(counting>=3)counting=0;
}


/** @param {NS} ns */
export async function main(ns) {

  // 1. 选择目标
  var targetServerName = getTargetServer(ns);
  ns.tprint("目前最富的服务器:",targetServerName );
  var objTargetServer =ns.getServer(targetServerName); 
  // var hackDifficulty = objTargetServer.hackDifficulty;
  // ns.tprint("目标服务器的成功率:",hackDifficulty,"%");
  // ns.tprint("目标服务器的最小成功率:",objTargetServer.minDifficulty,"%");
  var MinSecurity = ns.getServerMinSecurityLevel(targetServerName);
  ns.tprint("目标服务器的最小Security:",MinSecurity);
  var securityLevel = ns.getServerSecurityLevel(targetServerName);
  ns.tprint("目标服务器securityLevel:",securityLevel);
  var growOfTarget = ns.getServerGrowth(targetServerName);
  ns.tprint("目标服务器growth:",growOfTarget);
  var chanceOfHack = ns.hackAnalyzeChance(targetServerName);
  ns.tprint("目标服务器chanceOfHack:",Math.floor(chanceOfHack*100),"%");
  // 2. 黑掉现阶段可黑的服务器
  var allHackedServer = rootAllServer(ns);
  ns.tprint("已root所有服务器");
  // 3. 拷所有的脚本到执行服务器
  for(let i=0;i<allHackedServer.length;++i)
  {
    let strServerName = allHackedServer[i];
    const scriptPath="/hack_prepare/hack-elementary.js";
    ns.scp(scriptPath,strServerName,"home");
    var maxRam = ns.getServerMaxRam(strServerName);
    var usedRam = ns.getServerUsedRam(strServerName);
    var remainRam =     maxRam - usedRam;
    // 4. 执行 黑目标
    // 取可执行线程数:
    let numberThreads = Math.floor(remainRam/ns.getScriptRam(scriptPath));
    // ns.tprint("\n");
    // ns.tprint(ns.getServerMaxRam(strServerName),"/",ns.getScriptRam(scriptPath)," = ",numberThreads);
    if(numberThreads)
    { 
      ns.exec(scriptPath,strServerName,numberThreads,targetServerName);
    }
    // 取服务器上剩余内存
    usedRam = ns.getServerUsedRam(strServerName);
    remainRam =     maxRam - usedRam;
    if(remainRam>=1.75)
    {
      execScriptOnServer(ns,strServerName,targetServerName);
    }
  }// END for

  


}